home *** CD-ROM | disk | FTP | other *** search
- /*************************************************************************
- Talk Service written by Jeffrey A. Litz
-
- litz@cs.uwp.edu -or- Jeff_Litz@EDTNG.Kenosha.WI.US
-
- Copyright ©1994 JL Productions.
- *************************************************************************/
-
- #include <exec/types.h>
- #include <exec/memory.h>
- #include <exec/ports.h>
- #include <exec/semaphores.h>
- #include <exec/io.h>
- #include <devices/printer.h>
- #include <devices/timer.h>
- #include <devices/parallel.h>
- #include <devices/serial.h>
-
- #include <intuition/intuition.h>
- #include <intuition/classes.h>
- #include <intuition/classusr.h>
- #include <intuition/imageclass.h>
- #include <intuition/gadgetclass.h>
- #include <libraries/gadtools.h>
- #include <graphics/displayinfo.h>
- #include <graphics/gfxbase.h>
- #include <clib/intuition_protos.h>
- #include <clib/gadtools_protos.h>
- #include <clib/graphics_protos.h>
-
- #include <envoy/nipc.h>
- #include <envoy/services.h>
-
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/nipc_pragmas.h>
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/utility_pragmas.h>
-
- #include <utility/tagitem.h>
- #include <clib/dos_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/nipc_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/utility_protos.h>
-
- #include <string.h>
-
- #include "tkbase.h"
-
- #define GD_Gadget00 0
- #define GD_Gadget10 1
-
- #define TKCMD_TALK 1
- #define TKCMD_ABORT 2
- #define TKCMD_DATA 3
-
- extern STRPTR TALKUser;
- extern STRPTR TALKPassword;
- extern STRPTR TALKEntityName;
- extern ULONG TALKSignalMask;
- extern ULONG TALKError;
- extern struct Task *TALKSMProc;
-
- extern __far TALKServer(void);
-
- struct Library *GadToolsBase,*IntuitionBase;
-
-
- /*************************************************************************/
- /*************************************************************************/
- /* Generic Requester */
-
- struct Screen *Scr = NULL;
- APTR VisualInfo = NULL;
- struct Window *Project0Wnd = NULL;
- struct Gadget *Project0GList = NULL;
- struct Gadget *Project0Gadgets[2];
- UWORD Project0Left = 0;
- UWORD Project0Top = 0;
- UWORD Project0Width = 278;
- UWORD Project0Height = 55;
- UBYTE *Project0Wdt = "** TALK REQUESTED **";
-
- struct TextAttr topaz8 = {
- ( STRPTR )"topaz.font", 8, 0x00, 0x00 };
-
- struct IntuiText Project0IText[] = {
- 1, 0, JAM1,40, 7, &topaz8, NULL, NULL };
-
- /* VERY Quick kludge for long names */
- struct IntuiText Project0IText1[] = {
- 1, 0, JAM1,40, 7, &topaz8, NULL, NULL };
- struct IntuiText Project0IText2[] = {
- 1, 0, JAM1,40, 7, &topaz8, NULL, NULL };
-
-
- long SetupScreen( void )
- {
- if ( NOT( Scr = LockPubScreen( NULL )))
- return( 1L );
-
- if ( NOT( VisualInfo = GetVisualInfo( Scr, TAG_DONE )))
- return( 2L );
-
- return( NULL );
- }
-
- void CloseDownScreen( void )
- {
- if ( VisualInfo ) {
- FreeVisualInfo( VisualInfo );
- VisualInfo = NULL;
- }
-
- if ( Scr ) {
- UnlockPubScreen( NULL, Scr );
- Scr = NULL;
- }
- }
-
-
- void Project0Render(void)
- {
- /* VERY Quick kludge to work with long names */
-
- UWORD offy;
- WORD xpos;
- WORD two;
-
- UBYTE str1[36];
- UBYTE str2[36];
-
- offy = Project0Wnd->BorderTop;
-
- Project0IText1->IText=&str1[0];
- Project0IText2->IText=&str2[0];
-
- if(strlen(Project0IText->IText) > 32)
- {
- strncpy(Project0IText1->IText,Project0IText->IText,32);
- Project0IText1->IText[32]=0;
- strncpy(Project0IText2->IText,&Project0IText->IText[32],32);
- two=3;
- } else
- {
- strcpy(Project0IText1->IText,Project0IText->IText);
- two=7;
- }
-
-
- if((xpos=Project0Width-IntuiTextLength(Project0IText1)) < 0)
- xpos=0;
- Project0IText1->LeftEdge=xpos>>1;
-
- PrintIText( Project0Wnd->RPort, Project0IText1, 0, offy+two );
- two += 9;
-
- if(two==12)
- {
- if((xpos=Project0Width-IntuiTextLength(Project0IText2)) < 0)
- xpos=0;
- Project0IText2->LeftEdge=xpos>>1;
-
- PrintIText( Project0Wnd->RPort, Project0IText2, 0, offy+two );
- }
- }
-
- long OpenProject0Window(char *hostname)
- {
- struct NewGadget ng;
- struct Gadget *g;
- UWORD offx, offy;
-
- offx = Scr->WBorLeft;
- offy = Scr->WBorTop + Scr->RastPort.TxHeight + 1;
-
- if ( NOT( g = CreateContext( &Project0GList )))
- return( 1L );
-
- ng.ng_LeftEdge = offx + 10;
- ng.ng_TopEdge = offy + 35;
- ng.ng_Width = 76;
- ng.ng_Height = 16;
- ng.ng_GadgetText = (UBYTE *)"TALK";
- ng.ng_TextAttr = &topaz8;
- ng.ng_GadgetID = GD_Gadget00;
- ng.ng_Flags = PLACETEXT_IN;
- ng.ng_VisualInfo = VisualInfo;
-
- g = CreateGadget( BUTTON_KIND, g, &ng, TAG_DONE );
-
- Project0Gadgets[ 0 ] = g;
-
- ng.ng_LeftEdge = offx + 176;
- ng.ng_Width = 83;
- ng.ng_GadgetText = (UBYTE *)"IGNORE";
- ng.ng_GadgetID = GD_Gadget10;
-
- g = CreateGadget( BUTTON_KIND, g, &ng, TAG_DONE );
-
- Project0Gadgets[ 1 ] = g;
-
- if ( NOT g )
- return( 2L );
-
- if ( NOT( Project0Wnd = OpenWindowTags( NULL,
- WA_Left, Project0Left,
- WA_Top, Project0Top,
- WA_Width, Project0Width,
- WA_Height, Project0Height + offy,
- WA_IDCMP, BUTTONIDCMP|IDCMP_MENUPICK|IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW,
- WA_Flags, WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_SMART_REFRESH|WFLG_ACTIVATE,
- WA_Gadgets, Project0GList,
- WA_Title, Project0Wdt,
- WA_ScreenTitle, "Talk Service",
- WA_PubScreen, Scr,
- TAG_DONE )))
- return( 4L );
-
- GT_RefreshWindow( Project0Wnd, NULL );
-
- Project0IText->IText=hostname;
-
- Project0Render();
-
- return( NULL );
- }
-
- void CloseProject0Window( void )
- {
- if ( Project0Wnd ) {
- CloseWindow( Project0Wnd );
- Project0Wnd = NULL;
- }
-
- if ( Project0GList ) {
- FreeGadgets( Project0GList );
- Project0GList = NULL;
- }
- }
-
- /*************************************************************************/
- /*************************************************************************/
-
-
-
- /**************************************************************************
- O_Request() - Open a request on this machine
-
- When ever this service is "found", it attempts to bring workbench
- forward, open a requester and wait for a response. It will idle
- timeout in 15 seconds.
-
- INPUTS: hosename, entity, and entity signal
- OUTPUT: 0 means start a talk, 1 means "ignore" me
- **************************************************************************/
- UBYTE O_Request(char *hostname,void *entity,ULONG ent_sigbit)
- {
- struct IntuiMessage *mess;
- struct Transaction *w_trans;
- UBYTE r_value=2;
- struct MsgPort *TimerMP;
- struct timerequest *TimerIO;
- ULONG signal;
-
- if(TimerMP=CreateMsgPort())
- {
- if(TimerIO=(struct timerequest *)CreateExtIO(TimerMP,sizeof(struct timerequest)))
- {
- if(!(OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)TimerIO,0)))
- {
- if(IntuitionBase=OpenLibrary("intuition.library",37L))
- {
- if(GadToolsBase=OpenLibrary("gadtools.library",37L))
- {
- if(WBenchToFront())
- {
- if(!SetupScreen())
- {
- if(!OpenProject0Window(hostname))
- {
- TimerIO->tr_node.io_Command=TR_ADDREQUEST;
- TimerIO->tr_time.tv_secs=15;
- TimerIO->tr_time.tv_micro=0;
- SendIO((struct IORequest *)TimerIO);
-
- while(TRUE)
- {
- if(mess=(struct IntuiMessage *)GetMsg(Project0Wnd->UserPort))
- {
- if(mess->Class == IDCMP_GADGETUP)
- {
- r_value=((struct Gadget *)mess->IAddress)->GadgetID;
- }
- ReplyMsg((struct Message *)mess);
- } else if(w_trans=GetTransaction(entity))
- {
- w_trans->trans_Error=1;
- ReplyTransaction(w_trans);
- } else
- {
- signal=Wait((1<<Project0Wnd->UserPort->mp_SigBit) | (1<<ent_sigbit) | (1L << TimerMP->mp_SigBit));
- if(signal & (1L << TimerMP->mp_SigBit))
- {
- if(GetMsg(TimerMP))
- {
- r_value=1;
- }
- }
- }
- if(r_value != 2)
- {
- break;
- }
- }
-
- if(!(CheckIO((struct IORequest *)TimerIO)))
- {
- AbortIO((struct IORequest *)TimerIO);
- }
- WaitIO((struct IORequest *)TimerIO);
-
- CloseProject0Window();
- }
- CloseDownScreen();
- }
- } else
- {
- r_value=1;
- }
- CloseLibrary(GadToolsBase);
- }
- CloseLibrary(IntuitionBase);
- }
- CloseDevice((struct IORequest *)TimerIO);
- }
- DeleteExtIO((struct IORequest *)TimerIO);
- }
- DeleteMsgPort(TimerMP);
- }
- return(r_value);
- }
-
-
-
-
- /**************************************************************************
- StartService() - Starts the service.
-
- Services Manager calls this function to attempt to start the service.
-
- INPUTS: TagList passed in by Services Manager
- OUTPUT: Error Code - Non Zero Means Error
- **************************************************************************/
- ULONG __saveds ASM StartService(REG(a0) struct TagItem *st_list)
- {
- struct TagItem cptags[3];
- struct Process *lpdproc;
- BOOL status = FALSE;
- UBYTE sigbit;
- struct TagItem *tag;
-
-
- /* Check to see if service is already open */
-
- if(!TALKBase->TALK_Entity)
- {
- /* Nope - Try starting it up */
-
- if(sigbit = AllocSignal(-1L))
- {
- TALKSMProc = FindTask(0L);
- TALKSignalMask = (1L<<sigbit);
-
- cptags[0].ti_Tag = NP_Entry;
- cptags[0].ti_Data = (ULONG) TALKServer;
- cptags[1].ti_Tag = NP_Name;
- cptags[1].ti_Data = (ULONG) "TK Daemon";
- cptags[2].ti_Tag = TAG_DONE;
- cptags[2].ti_Data = NULL;
-
- /* Process tags passed in by services manager */
-
- if(tag=FindTagItem(SSVC_UserName,st_list))
- {
- TALKUser = (STRPTR) tag->ti_Data;
- }
-
- if(tag=FindTagItem(SSVC_Password,st_list))
- {
- TALKPassword = (STRPTR) tag->ti_Data;
- }
-
- if(tag=FindTagItem(SSVC_EntityName,st_list))
- {
- TALKEntityName = (STRPTR) tag->ti_Data;
- }
-
- /* Try to start the process */
-
- if(lpdproc = CreateNewProc((struct TagItem *)cptags))
- {
- Wait(1L<<sigbit);
- status = TRUE;
- }
- FreeSignal(sigbit);
- }
- }
- else
- {
- /* Service process already running... simply pass back its entity name */
-
- if(tag=FindTagItem(SSVC_EntityName,st_list))
- {
- strcpy((STRPTR)tag->ti_Data,"TK_Service");
- TALKError = 0;
- } else
- {
- TALKError = -1;
- }
- }
- return(TALKError);
- }
-
-
-
-
- VOID ASM GetServiceAttrsA(REG(a0) struct TagItem *tagList)
- {
- struct TagItem *ti;
-
- /* Return our service name - REQUIRED!!! */
- if(ti=FindTagItem( SVCAttrs_Name, tagList))
- {
- strcpy((STRPTR)ti->ti_Data,"Talk_Service");
- }
- }
-
-
-
-
- VOID ASM Server(REG(a0) STRPTR userName,REG(a1) STRPTR password,REG(a2) STRPTR EntityName)
- {
- struct Library *SvcBase;
- ULONG signals;
- ULONG waitmask;
- ULONG StartupError;
- ULONG ent_sigbit;
- struct MsgPort *port,*replyport;
- UBYTE host_name[256],userinput[256],work_space[512],sys_name[256];
- UBYTE done;
- BPTR output_w=0,input_w=0;
- int howmany;
- UBYTE logins=0;
- struct StandardPacket *packet;
- void *entity,*t_entity,*s_entity;
- struct Transaction *trans,*a_trans;
- struct TagItem cetags[4],cbtags[2],ttags[3];
-
- geta4();
-
- /* Initialize TagItems for entity and transaction creations */
-
- ent_sigbit = 0;
-
- cetags[0].ti_Tag=ENT_Name;
- cetags[0].ti_Data=(ULONG) "TK_Service";
- cetags[1].ti_Tag=ENT_Public;
- cetags[1].ti_Data=TRUE;
- cetags[2].ti_Tag=ENT_AllocSignal;
- cetags[2].ti_Data=(ULONG) &ent_sigbit;
- cetags[3].ti_Tag=TAG_END;
- cetags[3].ti_Data=0;
-
- cbtags[0].ti_Tag=ENT_AllocSignal;
- cbtags[0].ti_Data=NULL;
- cbtags[1].ti_Tag=TAG_END;
- cbtags[1].ti_Data=0;
-
- ttags[0].ti_Tag=TRN_AllocReqBuffer;
- ttags[0].ti_Data=516;
- ttags[1].ti_Tag=TRN_AllocRespBuffer;
- ttags[1].ti_Data=4;
- ttags[2].ti_Tag=TAG_END;
- ttags[2].ti_Data=0;
-
- StartupError = -1;
-
- if (SvcBase = OpenLibrary("talk.service", 0L))
- {
- /* Create an entity which everyone can find */
- if (entity = CreateEntityA((struct TagItem *) cetags))
- {
- /* Find out exactly who WE are */
- GetHostName(entity,host_name,255);
-
- /* Create an entity for RECEIVING data from outside */
- if(t_entity=CreateEntityA((struct TagItem *) cbtags))
- {
- /* Create a transaction for sending data */
- if(a_trans=AllocTransactionA((struct TagItem *) ttags))
- {
- /* Create a msgport for use in keyboard packet input */
- if(replyport=(struct MsgPort *) CreateMsgPort())
- {
- /* Setup our service entity and name */
- TALKBase->TALK_Entity = entity;
- strcpy(EntityName,"TK_Service");
-
- TALKError = StartupError = 0;
-
- /* Signal StartService() that everything appears to be OK and we are ready */
- Signal(TALKSMProc, TALKSignalMask);
-
- /* Setup waitmask for keyboard and transaction inputs */
- waitmask = (1<<replyport->mp_SigBit) | (1<<ent_sigbit);
-
- done=0;
-
- while(TRUE)
- {
- signals = Wait(waitmask);
-
- /* Did we receive a transaction */
- if(signals & (1<<ent_sigbit))
- {
- /* Get transaction */
- if(trans = GetTransaction(entity))
- {
- if((trans->trans_Command == TKCMD_DATA) && (logins))
- {
- /* Data transaction - send to output window */
- Write(output_w,(UBYTE *)((UBYTE *)trans->trans_RequestData+4),trans->trans_ReqDataActual-4);
- }
- if(trans->trans_Command == TKCMD_TALK)
- {
- /* Talk request - check to see if we are "busy" */
- if(logins)
- {
- /* YEP - already talking */
- trans->trans_Error=1;
- } else
- {
- logins=1;
-
- /* Find out what system wishes to talk by reading the transaction buffer */
- strcpy(sys_name,(UBYTE *)((UBYTE *)trans->trans_RequestData+4));
-
- /* Open a requester */
- if(!O_Request(sys_name,entity,ent_sigbit))
- {
- trans->trans_Error=3;
- done=3;
-
- /* Locate the entity to talk back to */
- if(s_entity=FindEntity(sys_name,"talk_back",t_entity,NULL))
- {
- /* Open windows and alloc & setup packet for waitforchar input */
- if(output_w=(BPTR)Open("CON:1/1/640/150/Output Window Service",MODE_NEWFILE))
- {
- if(input_w=(BPTR)Open("CON:1/150/640/50/Input Window Service/CLOSE",MODE_NEWFILE))
- {
- if(packet=(struct StandardPacket *)AllocMem((long)sizeof(struct StandardPacket),MEMF_PUBLIC|MEMF_CLEAR))
- {
- done=0;
- trans->trans_Error=0;
- port=(struct MsgPort *) (((struct FileHandle *)((ULONG)input_w<<2))->fh_Type);
- packet->sp_Msg.mn_Node.ln_Name=(char *)&(packet->sp_Pkt);
- packet->sp_Pkt.dp_Link=&(packet->sp_Msg);
- packet->sp_Pkt.dp_Port=replyport;
- packet->sp_Pkt.dp_Type=ACTION_WAIT_CHAR;
- packet->sp_Pkt.dp_Arg1=34000;
- SendPkt(&packet->sp_Pkt,port,replyport);
- }
- }
- }
- }
- } else
- {
- trans->trans_Error=2;
- done=1;
- }
- }
- }
-
- /* cancel talk */
- if(trans->trans_Command == TKCMD_ABORT)
- {
- trans->trans_Error=0;
- done=1;
- }
- ReplyTransaction(trans);
- }
- }
-
- /* Is it a keyboard input? */
- if(signals & (1<<replyport->mp_SigBit))
- {
- /* check to make sure we are actually connected to someone */
- if(logins)
- {
- /* check to make sure we actually received something */
- if(GetMsg(replyport))
- {
- if(packet->sp_Pkt.dp_Res1)
- {
- if(!(howmany=Read(input_w,userinput,255)))
- {
- /* Close gadget - exit talk */
- done=2;
- } else
- {
- /* send output to our window as well as to other side */
- userinput[howmany]=0;
- sprintf(work_space,"(%s) %s\n",host_name,userinput);
-
- Write(output_w,work_space,strlen(work_space));
-
- a_trans->trans_Command=TKCMD_DATA;
- *(ULONG *)(a_trans->trans_RequestData)=*(ULONG *)(a_trans->trans_ResponseData);
- strcpy(((UBYTE *)a_trans->trans_RequestData+4),work_space);
- a_trans->trans_ReqDataActual=strlen(work_space)+4;
- a_trans->trans_Timeout=10;
- DoTransaction(s_entity,t_entity,a_trans);
- }
- }
- /* send a packet for another waitforchar input */
- packet->sp_Pkt.dp_Port=replyport;
- packet->sp_Pkt.dp_Type=ACTION_WAIT_CHAR;
- packet->sp_Pkt.dp_Arg1=34000;
- SendPkt(&packet->sp_Pkt,port,replyport);
- }
- }
- }
- if(done)
- {
- break;
- }
- }
- if(done == 2)
- {
- /* If we are initating the close - attempt to signal other side */
- howmany=4;
- while(howmany--)
- {
- a_trans->trans_ReqDataActual=4;
- a_trans->trans_Command=TKCMD_ABORT;
- a_trans->trans_Timeout=10;
- DoTransaction(s_entity,t_entity,a_trans);
- if(a_trans->trans_Error==0)
- {
- break;
- }
- }
- }
-
- /* Attempt to clean up any stray transactions */
- while(trans = GetTransaction(entity))
- {
- trans->trans_Error=2;
- ReplyTransaction(trans);
- }
-
- /* General clean up - close everything down and dealloc */
-
- TALKBase->TALK_Entity = NULL;
-
- while((ULONG *)GetMsg(replyport) != (ULONG *)&packet->sp_Msg);
- if(output_w)
- Close(output_w);
- if(input_w)
- Close(input_w);
- if(s_entity)
- LoseEntity(s_entity);
- if(packet)
- FreeMem(packet,(long)sizeof(struct StandardPacket));
- DeleteMsgPort(replyport);
- }
- a_trans->trans_ReqDataLength=516;
- FreeTransaction(a_trans);
- }
- DeleteEntity(t_entity);
- }
- DeleteEntity(entity);
- }
- if(StartupError)
- {
- /* Oooppsss - there was a startup problem - signal StartService() */
- TALKError = StartupError;
- Signal(TALKSMProc, TALKSignalMask);
- }
- Forbid();
- CloseLibrary(SvcBase);
- }
- }
-